package jp.co.cyberagent.android.gpuimage.filter;

import android.opengl.GLES20;

public class GPUImageSoulFilter extends GPUImageFilter {
    public static final String SOUL_FRAGMENT_SHADER = "" +
            "precision highp float;\n" +
            "// 纹理采样器\n" +
            "uniform sampler2D inputImageTexture;\n" +
            "// 纹理坐标\n" +
            "varying vec2 textureCoordinate;\n" +
            "// 时间撮\n" +
            "uniform float Time;\n" +
            "\n" +
            "void main (void) {\n" +
            "    // 一次灵魂出窍效果的时长 0.7\n" +
            "    float duration = 0.7;\n" +
            "    // 透明度上限\n" +
            "    float maxAlpha = 0.4;\n" +
            "    // 放大图片上限\n" +
            "    float maxScale = 1.8;\n" +
            "    \n" +
            "    // 进度值[0,1]\n" +
            "    float progress = mod(Time, duration) / duration; // 0~1\n" +
            "    // 透明度[0,0.4]\n" +
            "    float alpha = maxAlpha * (1.0 - progress);\n" +
            "    // 缩放比例[1.0,1.8]\n" +
            "    float scale = 1.0 + (maxScale - 1.0) * progress;\n" +
            "    \n" +
            "    // 放大纹理坐标\n" +
            "    // 根据放大比例，得到放大纹理坐标 [0,0],[0,1],[1,1],[1,0]\n" +
            "    float weakX = 0.5 + (textureCoordinate.x - 0.5) / scale;\n" +
            "    float weakY = 0.5 + (textureCoordinate.y - 0.5) / scale;\n" +
            "    // 放大纹理坐标\n" +
            "    vec2 weakTextureCoords = vec2(weakX, weakY);\n" +
            "    \n" +
            "    // 获取对应放大纹理坐标下的纹素(颜色值rgba)\n" +
            "    vec4 weakMask = texture2D(inputImageTexture, weakTextureCoords);\n" +
            "   \n" +
            "    // 原始的纹理坐标下的纹素(颜色值rgba)\n" +
            "    vec4 mask = texture2D(inputImageTexture, textureCoordinate);\n" +
            "    \n" +
            "    // 颜色混合 默认颜色混合方程式 = mask * (1.0-alpha) + weakMask * alpha;\n" +
            "    gl_FragColor = mask * (1.0 - alpha) + weakMask * alpha;\n" +
            "}\n";

    private int uniformTimeLocation;
    private float time = 0.5f;

    public GPUImageSoulFilter() {
        super(NO_FILTER_VERTEX_SHADER, SOUL_FRAGMENT_SHADER);
    }

    @Override
    public void onInit() {
        super.onInit();
        uniformTimeLocation = GLES20.glGetUniformLocation(getProgram(), "Time");
    }

    @Override
    public void onInitialized() {
        super.onInitialized();
        setTime(time);
    }

    public void setTime(final float time) {
        this.time = time;
        setFloat(uniformTimeLocation, time);
    }
}
